import json
import decimal
import requests
from flask import Flask, jsonify, Response, request, g
from fullstack import app, api, db
from flask_restful import Resource
from fullstack.Models.member.Member import Member
from fullstack.Models.member.MemberAddress import MemberAddress
from fullstack.Models.member.OauthMemberBind import OauthMemberBind
from fullstack.Models.food.Food import Food
from fullstack.Models.food.FoodSaleChangeLog import FoodSaleChangeLog
from fullstack.Models.pay.PayOrder import PayOrder
from fullstack.Models.pay.PayOrderItem import PayOrderItem
from fullstack.Models.ShoppingCart import ShoppingCart
from fullstack.WeChat.Service.CartService import CartService
from fullstack.WeChat.Service.FoodService import FoodService
from fullstack.WeChat.Service.PayService import PayService
from fullstack.WeChat.Service.WeChatService import WeChatService
from fullstack.utils import getCurrentTime, getDictFilterField, selectFilterObj

# URL部分
SECTION_URL = '/wechat/api/order'

# 订单信息


class OrderInfo(Resource):
    def post(self):
        resp = {'code': 200, 'msg': '操作成功~', 'data': {}}
        req = request.values
        params_goods = req['goods'] if 'goods' in req else None
        member_info = g.member_info
        params_goods_list = []
        if params_goods:
            params_goods_list = json.loads(params_goods)

        food_dic = {}
        for item in params_goods_list:
            food_dic[item['id']] = item['number']

        food_ids = food_dic.keys()
        food_list = Food.query.filter(Food.id.in_(food_ids)).all()
        data_food_list = []
        yun_price = pay_price = decimal.Decimal(0.00)
        if food_list:
            for item in food_list:
                tmp_data = {
                    "id": item.id,
                    "name": item.name,
                    "price": str(item.price),
                    'pic_url': item.imageURL,
                    'number': food_dic[item.id]
                }
                pay_price = pay_price + item.price * int(food_dic[item.id])
                data_food_list.append(tmp_data)

        # 获取地址
        address_info = MemberAddress.query.filter_by(
            is_default=1, member_id=member_info.id, status=1).first()
        default_address = ''
        if address_info:
            default_address = {
                "id": address_info.id,
                "name": address_info.nickname,
                "mobile": address_info.mobile,
                "address": "%s%s%s%s" % (address_info.province_str, address_info.city_str, address_info.area_str, address_info.address)
            }

        resp['data']['food_list'] = data_food_list
        resp['data']['pay_price'] = str(pay_price)
        resp['data']['yun_price'] = str(yun_price)
        resp['data']['total_price'] = str(pay_price + yun_price)
        resp['data']['default_address'] = default_address
        return jsonify(resp)


api.add_resource(OrderInfo, SECTION_URL+'/info')


# 订单提交
class OrderCreate(Resource):
    def post(self):
        resp = {'code': 200, 'msg': '操作成功~', 'data': {}}
        req = request.values
        type = req['type'] if 'type' in req else ''
        note = req['note'] if 'note' in req else ''
        express_address_id = int(
            req['express_address_id']) if 'express_address_id' in req and req['express_address_id'] else 0
        params_goods = req['goods'] if 'goods' in req else None

        items = []
        if params_goods:
            items = json.loads(params_goods)

        if len(items) < 1:
            resp['code'] = -1
            resp['msg'] = "下单失败：没有选择商品~~"
            return jsonify(resp)

        address_info = MemberAddress.query.filter_by(
            id=express_address_id).first()
        if not address_info or not address_info.status:
            resp['code'] = -1
            resp['msg'] = "下单失败：快递地址不对~~"
            return jsonify(resp)

        member_info = g.member_info
        target = PayService()
        params = {
            "note": note,
            'express_address_id': address_info.id,
            'express_info': {
                'mobile': address_info.mobile,
                'nickname': address_info.nickname,
                "address": "%s%s%s%s" % (address_info.province_str, address_info.city_str, address_info.area_str, address_info.address)
            }
        }
        resp = target.createOrder(member_info.id, items, params)
        current_time = getCurrentTime()
        # 向food_sale_change_log写入记录
        if resp['data']:
            for item in items:
                model_sale = FoodSaleChangeLog()
                model_sale.food_id = item['id']
                model_sale.order_id = resp['data']['id']
                model_sale.price = item['price']
                model_sale.quantity = item['number']
                model_sale.member_id = g.member_info.id
                model_sale.status = 0
                model_sale.created_time = current_time
                db.session.add(model_sale)
                db.session.commit()

        # 如果是来源购物车的，下单成功将下单的商品去掉
        if resp['code'] == 200 and type == "cart":
            CartService.deleteItem(member_info.id, items)

        return jsonify(resp)


api.add_resource(OrderCreate, SECTION_URL+'/create')


# 支付
class OrderPay(Resource):
    def post(self):
        resp = {'code': 200, 'msg': '操作成功~', 'data': {}}
        member_info = g.member_info
        req = request.values
        order_sn = req['order_sn'] if 'order_sn' in req else ''
        pay_order_info = PayOrder.query.filter_by(
            order_sn=order_sn, member_id=member_info.id).first()
        if not pay_order_info:
            resp['code'] = -1
            resp['msg'] = "系统繁忙。请稍后再试~~"
            return jsonify(resp)

        oauth_bind_info = OauthMemberBind.query.filter_by(
            member_id=member_info.id).first()
        if not oauth_bind_info:
            resp['code'] = -1
            resp['msg'] = "系统繁忙。请稍后再试~~"
            return jsonify(resp)

        pay_order_info.status = 1
        pay_order_info.express_status = -7
        db.session.add(pay_order_info)
        db.session.commit()
        # 将food_sale_change_log status从0变成1
        order_id = int(req['pay_order_id'])
        # 批量更新
        db.session.query(FoodSaleChangeLog).filter_by(
            order_id=order_id).update({FoodSaleChangeLog.status: 1})
        db.session.commit()
        # 更新总销售数量
        item_model=PayOrderItem.query.filter_by(pay_order_id=order_id,status=1)
        if item_model:
            for item in item_model:
                food_model=Food.query.filter_by(id=item.food_id).first()
                if food_model:
                    food_model.total_count=food_model.total_count+item.quantity
                    db.session.add(food_model)
                    db.session.commit()
        return jsonify(resp)

        # test-------------------------------------
        # member_info = g.member_info
        # req = request.values
        # order_sn = req['order_sn'] if 'order_sn' in req else ''
        # pay_order_info = PayOrder.query.filter_by( order_sn = order_sn,member_id = member_info.id ).first()
        # if not pay_order_info:
        #     resp['code'] = -1
        #     resp['msg'] = "系统繁忙。请稍后再试~~"
        #     return jsonify(resp)

        # oauth_bind_info = OauthMemberBind.query.filter_by( member_id =  member_info.id ).first()
        # if not oauth_bind_info:
        #     resp['code'] = -1
        #     resp['msg'] = "系统繁忙。请稍后再试~~"
        #     return jsonify(resp)
        # config_mina = app.config['WX_APP']
        # notify_url = app.config['APP']['domain'] + config_mina['callback_url']

        # target_wechat = WeChatService( merchant_key=config_mina['paykey'] )

        # data = {
        #     'appid': config_mina['appid'],
        #     'mch_id': config_mina['mch_id'],
        #     'nonce_str': target_wechat.get_nonce_str(),
        #     'body': '订餐',  # 商品描述
        #     'out_trade_no': pay_order_info.order_sn,  # 商户订单号
        #     'total_fee': int( pay_order_info.total_price * 100 ),
        #     'notify_url': notify_url,
        #     'trade_type': "JSAPI",
        #     'openid': oauth_bind_info.openid
        # }

        # pay_info = target_wechat.get_pay_info( pay_data=data)

        # #保存prepay_id为了后面发模板消息
        # pay_order_info.prepay_id = pay_info['prepay_id']
        # db.session.add( pay_order_info )
        # db.session.commit()

        # resp['data']['pay_info'] = pay_info
        # return jsonify(resp)


api.add_resource(OrderPay, SECTION_URL+'/pay')

# 订单回滚


class OrderCallback(Resource):
    def post(self):
        result_data = {
            'return_code': 'SUCCESS',
            'return_msg': 'OK'
        }
        header = {'Content-Type': 'application/xml'}
        config_mina = app.config['WX_APP']
        target_wechat = WeChatService(merchant_key=config_mina['paykey'])
        callback_data = target_wechat.xml_to_dict(request.data)
        app.logger.info(callback_data)
        sign = callback_data['sign']
        callback_data.pop('sign')
        gene_sign = target_wechat.create_sign(callback_data)
        app.logger.info(gene_sign)
        if sign != gene_sign:
            result_data['return_code'] = result_data['return_msg'] = 'FAIL'
            return target_wechat.dict_to_xml(result_data), header
        if callback_data['result_code'] != 'SUCCESS':
            result_data['return_code'] = result_data['return_msg'] = 'FAIL'
            return target_wechat.dict_to_xml(result_data), header

        order_sn = callback_data['out_trade_no']
        pay_order_info = PayOrder.query.filter_by(order_sn=order_sn).first()
        if not pay_order_info:
            result_data['return_code'] = result_data['return_msg'] = 'FAIL'
            return target_wechat.dict_to_xml(result_data), header

        if int(pay_order_info.total_price * 100) != int(callback_data['total_fee']):
            result_data['return_code'] = result_data['return_msg'] = 'FAIL'
            return target_wechat.dict_to_xml(result_data), header

        if pay_order_info.status == 1:
            return target_wechat.dict_to_xml(result_data), header

        target_pay = PayService()
        target_pay.orderSuccess(pay_order_id=pay_order_info.id, params={
                                "pay_sn": callback_data['transaction_id']})
        target_pay.addPayCallbackData(
            pay_order_id=pay_order_info.id, data=request.data)
        return target_wechat.dict_to_xml(result_data), header


api.add_resource(OrderCallback, SECTION_URL+'/callback')

# 订单选择


class OrderOps(Resource):
    def post(self):
        resp = {'code': 200, 'msg': '操作成功~', 'data': {}}
        req = request.values
        member_info = g.member_info
        order_sn = req['order_sn'] if 'order_sn' in req else ''
        act = req['act'] if 'act' in req else ''
        pay_order_info = PayOrder.query.filter_by(
            order_sn=order_sn, member_id=member_info.id).first()
        if not pay_order_info:
            resp['code'] = -1
            resp['msg'] = "系统繁忙。请稍后再试~~"
            return jsonify(resp)

        if act == "cancel":
            target_pay = PayService()
            ret = target_pay.closeOrder(pay_order_id=pay_order_info.id)
            if not ret:
                resp['code'] = -1
                resp['msg'] = "系统繁忙。请稍后再试~~"
                return jsonify(resp)
        elif act == "confirm":
            pay_order_info.express_status = 1
            pay_order_info.updated_time = getCurrentTime()
            db.session.add(pay_order_info)
            db.session.commit()

        return jsonify(resp)


api.add_resource(OrderOps, SECTION_URL+'/ops')
